using System.Drawing;
using Wilco.SyntaxHighlighting.Engine.Node.Occurrence;

namespace Wilco.SyntaxHighlighting.Engine.Node
{
    /// <summary>
    /// Provides an abstract node class.
    /// </summary>
    public abstract class NodeBase : INode
    {
        private Color backColor;
        private Color foreColor;
        private Font font;
        private string navigateUrl;
        private readonly OccurrenceCollection occurrences;

        /// <summary>
        /// Occurs when a new occurrence is added to the <see cref="INode.Occurrences"/>.
        /// </summary>
        public event OccurrenceEventHandler OccurrenceAdded;

        /// <summary>
        /// Occurs when an occurrence is removed from the <see cref="INode.Occurrences"/>.
        /// </summary>
        public event OccurrenceEventHandler OccurrenceRemoved;

        /// <summary>
        /// Gets or sets the foreground color of the node.
        /// </summary>
        public Color BackColor
        {
            get
            {
                return backColor;
            }
            set
            {
                if (value != backColor)
                {
                    backColor = value;
                }
            }
        }

        /// <summary>
        /// Gets or sets the font of the text represented by the occurrences of the node.
        /// </summary>
        public Font Font
        {
            get
            {
                return font;
            }
            set
            {
                if (value != font)
                {
                    font = value;
                }
            }
        }

        /// <summary>
        /// Gets or sets the foreground color of the node.
        /// </summary>
        public Color ForeColor
        {
            get
            {
                return foreColor;
            }
            set
            {
                if (value != foreColor)
                {
                    foreColor = value;
                }
            }
        }

        /// <summary>
        /// Gets or sets the navigate Url.
        /// </summary>
        public string NavigateUrl
        {
            get
            {
                return navigateUrl;
            }
            set
            {
                if (value != navigateUrl)
                {
                    navigateUrl = value;
                }
            }
        }

        /// <summary>
        /// Gets a collection of occurrences of the <see cref="INode"/> implementation.
        /// </summary>
        public OccurrenceCollection Occurrences
        {
            get
            {
                return occurrences;
            }
        }

        /// <summary>
        /// Initializes a new instance of a <see cref="NodeBase"/> class.
        /// </summary>
        public NodeBase()
        {
            backColor = Color.Transparent;
            foreColor = Color.Black;
            font = new Font(new FontFamily("Courier New"), 10, GraphicsUnit.Point);
            occurrences = new OccurrenceCollection();
            occurrences.OccurrenceAdded += this.occurrences_OccurrenceAdded;
            occurrences.OccurrenceRemoved += this.occurrences_OccurrenceRemoved;
        }

        /// <summary>
        /// Handles the occurrence added event.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void occurrences_OccurrenceAdded(object sender, OccurrenceEventArgs e)
        {
            OnOccurrenceAdded(e);
        }

        /// <summary>
        /// Handles the occurrence removed event.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void occurrences_OccurrenceRemoved(object sender, OccurrenceEventArgs e)
        {
            OnOccurrenceRemoved(e);
        }

        /// <summary>
        /// Raises the <see cref="NodeBase.OccurrenceAdded"/> event.
        /// </summary>
        /// <param name="e">An <see cref="OccurrenceEventArgs"/> that contains the event data.</param>
        protected virtual void OnOccurrenceAdded(OccurrenceEventArgs e)
        {
            if (OccurrenceAdded != null)
                OccurrenceAdded(this, e);
        }

        /// <summary>
        /// Raises the <see cref="NodeBase.OccurrenceRemoved"/> event.
        /// </summary>
        /// <param name="e">An <see cref="OccurrenceEventArgs"/> that contains the event data.</param>
        protected virtual void OnOccurrenceRemoved(OccurrenceEventArgs e)
        {
            if (OccurrenceRemoved != null)
                OccurrenceRemoved(this, e);
        }
    }
}